﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using Net.Chirash.Twitter.TwitterDatabase;

namespace Net.Chirash.Twitter.TwitterClient
{
    public class TwitterDataCollection<T>
        : IEnumerable<T>
       where T : TwitterData
    {
        public TwitterDataCollection(IEnumerable<T> list)
        {
            DataList = list;
        }

        public virtual IEnumerable<T> DataList { get; private set; }

        public IEnumerator<T> GetEnumerator()
        {
            return DataList.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return DataList.GetEnumerator();
        }
    }

    public class TwitterLocatedCollection<T>
        : TwitterDataCollection<T>, ITwitterLocatable
        where T : TwitterData
    {
        public TwitterLocatedCollection(IEnumerable<T> list, long prevCursor, long nextCursor)
            : base(list)
        {
            this.PreviousCursor = prevCursor;
            this.NextCursor = nextCursor;

        }

        public long PreviousCursor { get; private set; }
        public long NextCursor { get; private set; }

        protected static void ParseCursor(string xmlContent, out long prevCursor, out long nextCursor)
        {
            ParseCursor(XElement.Parse(xmlContent), out prevCursor, out nextCursor);
        }

        protected static void ParseCursor(XElement e, out long prevCursor, out long nextCursor)
        {
            prevCursor = -1;
            nextCursor = -1;
            long.TryParse(e.Element("previous_cursor").Value, out prevCursor);
            long.TryParse(e.Element("next_cursor").Value, out nextCursor);
        }

    }

    public class UserList
        : TwitterLocatedCollection<User>
    {
        public UserList(IEnumerable<User> list, long prevCursor, long nextCursor)
            : base(list, prevCursor, nextCursor)
        {
        }

        public UserList(IEnumerable<User> list)
            : this(list, -1, -1)
        {
        }

        public UserList()
            : this(new User[0])
        {
        }

        public static UserList ParseAll(string xml)
        {
            List<User> list = new List<User>();
            XElement element = XElement.Parse(xml);
            foreach (var user in element.Descendants("user"))
            {
                list.Add(new User().Parse(user.ToString()));
            }

            long prevCur, nextCur;
            ParseCursor(element, out prevCur, out nextCur);
            return new UserList(list: list,
                                prevCursor: prevCur,
                                nextCursor: nextCur);
        }
    }

    public class DirectMessageCollection
        : TwitterDataCollection<DirectMessage>
    {
        public DirectMessageCollection(IEnumerable<DirectMessage> list)
            : base(list)
        {
        }

        public DirectMessageCollection()
            : this(new DirectMessage[0])
        {
        }

        /// <summary>
        /// Parse DirectMessages XML Text for DirectMessages
        /// </summary>
        /// <param name="xml">DirectMessages XML to parse</param>
        /// <returns>DirectMessages</returns>
        public static DirectMessageCollection ParseAll(string xml)
        {
            List<DirectMessage> list = new List<DirectMessage>();
            foreach (XElement element in XElement.Parse(xml).Elements("direct_message"))
            {
                list.Add(new DirectMessage().Parse(element.ToString()));
            }
            return new DirectMessageCollection(list);
        }

    }

    public class TwitterListCollection
        : TwitterLocatedCollection<TwitterList>
    {
        public TwitterListCollection(IEnumerable<TwitterList> lists, long prevCursor, long nextCursor)
            : base(lists, prevCursor, nextCursor)
        {
        }

        public TwitterListCollection(IEnumerable<TwitterList> lists)
            : this(lists, -1, -1)
        {
        }

        public TwitterListCollection()
            : this(new TwitterList[0])
        { }

        public static TwitterListCollection ParseAll(string xml)
        {
            var list = new System.Collections.Generic.List<TwitterList>();
            var element = XElement.Parse(xml);
            foreach (var e in element.Descendants("list"))
            {
                list.Add(new TwitterList().Parse(e.ToString()));
            }
            long prevCur, nextCur;
            ParseCursor(element, out prevCur, out nextCur);
            return new TwitterListCollection(list,
                                             prevCursor: prevCur,
                                             nextCursor: nextCur);
        }
    }

}
